/*  Copyright (c) 2012 Xiaoyun Zhu
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy  
 *  of this software and associated documentation files (the "Software"), to deal  
 *  in the Software without restriction, including without limitation the rights  
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 *  copies of the Software, and to permit persons to whom the Software is  
 *  furnished to do so, subject to the following conditions:
 *  
 *  The above copyright notice and this permission notice shall be included in  
 *  all copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN  
 *  THE SOFTWARE.  
 */
package cn.kk.fluidcells;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.GroupLayout;
import javax.swing.LayoutStyle;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

import cn.kk.fluidcells.api.CellPlugin;
import cn.kk.fluidcells.base.Status;
import cn.kk.fluidcells.ui.ClosableDialog;
import cn.kk.fluidcells.ui.SettingsPanel;

public class Main extends javax.swing.JFrame implements ActionListener {
    private static final long serialVersionUID = -2144232267378750425L;
    private static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();

    private final List<CellPlugin> cells;

    /**
     * Creates new form Find
     * 
     * @throws IOException
     */
    public Main() throws IOException {
        this.cells = Main.loadCells();
        setIconImage(ImageIO.read(getClass().getResource("/fluidcells.png")));
        initComponents();

        setLocation((Main.SCREEN_SIZE.width - getWidth()) / 2, (Main.SCREEN_SIZE.height - getHeight()) / 2);
    }

    private static List<CellPlugin> loadCells() {
        try {
            List<URL> foundPlugins = CellPluginsHelper.findCellPlugins(new File("plugins"));
            List<URL> loadedPlugins = CellPluginsHelper.loadCellPlugins(foundPlugins);
        } catch (Exception e) {
            System.err.println("Failed to load plugins.");
        }
        CellPluginService pluginService = CellPluginService.getInstance();
        return pluginService.initCells();
    }

    /**
     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
     * content of this method is always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        this.cbRecentFiles = new javax.swing.JComboBox();
        this.btnRecord = new javax.swing.JButton();
        this.btnPlay = new javax.swing.JButton();
        this.btnOptions = new javax.swing.JButton();
        this.pnlKeyboard = new javax.swing.JPanel();
        this.lblKeyboard = new javax.swing.JLabel();
        this.pnlMouse = new javax.swing.JPanel();
        this.lblColor = new javax.swing.JLabel();
        this.lblMouse = new javax.swing.JLabel();
        this.pnlStep = new javax.swing.JPanel();
        this.lblStep = new javax.swing.JLabel();
        this.pnlZoom = new javax.swing.JPanel();
        this.pnlTime = new javax.swing.JPanel();
        this.lblTime = new javax.swing.JLabel();
        this.cbProcess = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("游离细胞");
        setAlwaysOnTop(true);
        setName("frmMain");
        setResizable(false);

        this.cbRecentFiles.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
            "[ 创建新文件 ]"
        }));

        this.btnRecord.setIcon(new javax.swing.ImageIcon(getClass().getResource("/btn_record.png"))); // NOI18N
        this.btnRecord.setToolTipText("录制文件");
        this.btnRecord.setActionCommand("record");
        this.btnRecord.addActionListener(this);

        this.btnPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/btn_play.png"))); // NOI18N
        this.btnPlay.setToolTipText("播放文件");
        this.btnPlay.setActionCommand("play");
        this.btnPlay.addActionListener(this);

        this.btnOptions.setIcon(new javax.swing.ImageIcon(getClass().getResource("/btn_edit.png"))); // NOI18N
        this.btnOptions.setToolTipText("编辑选项");
        this.btnOptions.setActionCommand("options");
        this.btnOptions.addActionListener(this);

        this.pnlKeyboard.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        this.lblKeyboard.setText("按键: 无");
        this.lblKeyboard.setToolTipText("键盘状态");

        GroupLayout pnlKeyboardLayout = new GroupLayout(this.pnlKeyboard);
        this.pnlKeyboard.setLayout(pnlKeyboardLayout);
        pnlKeyboardLayout.setHorizontalGroup(pnlKeyboardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(
                        pnlKeyboardLayout
                                .createSequentialGroup()
                                .addComponent(this.lblKeyboard, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE).addContainerGap()));
        pnlKeyboardLayout.setVerticalGroup(pnlKeyboardLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(
                        GroupLayout.Alignment.TRAILING,
                        pnlKeyboardLayout.createSequentialGroup().addGap(0, 0, Short.MAX_VALUE)
                                .addComponent(this.lblKeyboard)));

        this.pnlMouse.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        this.pnlMouse.setPreferredSize(new java.awt.Dimension(105, 4));

        this.lblColor.setText("#000000");
        this.lblColor.setToolTipText("鼠标状态");

        this.lblMouse.setText("x / y");
        this.lblMouse.setToolTipText("鼠标状态");

        GroupLayout pnlMouseLayout = new GroupLayout(this.pnlMouse);
        this.pnlMouse.setLayout(pnlMouseLayout);
        pnlMouseLayout.setHorizontalGroup(pnlMouseLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                pnlMouseLayout
                        .createSequentialGroup()
                        .addComponent(this.lblMouse, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,
                                Short.MAX_VALUE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(this.lblColor, GroupLayout.PREFERRED_SIZE, 52, GroupLayout.PREFERRED_SIZE)));
        pnlMouseLayout.setVerticalGroup(pnlMouseLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                GroupLayout.Alignment.TRAILING,
                pnlMouseLayout
                        .createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addGroup(
                                pnlMouseLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                        .addComponent(this.lblColor).addComponent(this.lblMouse))));

        this.pnlStep.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        this.pnlStep.setToolTipText("");
        this.pnlStep.setPreferredSize(new java.awt.Dimension(105, 4));

        this.lblStep.setText("步骤: 0 / 0");

        GroupLayout pnlStepLayout = new GroupLayout(this.pnlStep);
        this.pnlStep.setLayout(pnlStepLayout);
        pnlStepLayout.setHorizontalGroup(pnlStepLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(
                this.lblStep, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
        pnlStepLayout.setVerticalGroup(pnlStepLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                GroupLayout.Alignment.TRAILING,
                pnlStepLayout.createSequentialGroup().addGap(0, 0, Short.MAX_VALUE).addComponent(this.lblStep)));

        this.pnlZoom.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        GroupLayout pnlZoomLayout = new GroupLayout(this.pnlZoom);
        this.pnlZoom.setLayout(pnlZoomLayout);
        pnlZoomLayout.setHorizontalGroup(pnlZoomLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0,
                100, Short.MAX_VALUE));
        pnlZoomLayout.setVerticalGroup(pnlZoomLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 0,
                Short.MAX_VALUE));

        this.pnlTime.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        this.pnlTime.setToolTipText("");
        this.pnlTime.setPreferredSize(new java.awt.Dimension(105, 4));

        this.lblTime.setText("时间: 0:00:00 / 0:00:00");

        GroupLayout pnlTimeLayout = new GroupLayout(this.pnlTime);
        this.pnlTime.setLayout(pnlTimeLayout);
        pnlTimeLayout.setHorizontalGroup(pnlTimeLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(
                this.lblTime, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
        pnlTimeLayout.setVerticalGroup(pnlTimeLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                GroupLayout.Alignment.TRAILING,
                pnlTimeLayout.createSequentialGroup().addGap(0, 0, Short.MAX_VALUE).addComponent(this.lblTime)));

        this.cbProcess.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
            "目标窗口: 全屏"
        }));

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout
                .createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(
                        GroupLayout.Alignment.TRAILING,
                        layout.createSequentialGroup().addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(this.btnPlay).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(this.btnRecord).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(this.btnOptions).addGap(12, 12, 12))
                .addGroup(
                        layout.createSequentialGroup()
                                .addComponent(this.pnlZoom, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
                                        GroupLayout.PREFERRED_SIZE)
                                .addGroup(
                                        layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                .addGroup(
                                                        layout.createSequentialGroup()
                                                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                                .addGroup(
                                                                        layout.createParallelGroup(
                                                                                GroupLayout.Alignment.LEADING)
                                                                                .addComponent(this.pnlStep,
                                                                                        GroupLayout.DEFAULT_SIZE, 125,
                                                                                        Short.MAX_VALUE)
                                                                                .addComponent(this.pnlMouse,
                                                                                        GroupLayout.DEFAULT_SIZE, 125,
                                                                                        Short.MAX_VALUE)
                                                                                .addComponent(this.pnlTime,
                                                                                        GroupLayout.DEFAULT_SIZE, 125,
                                                                                        Short.MAX_VALUE)))
                                                .addGroup(
                                                        layout.createSequentialGroup()
                                                                .addGap(7, 7, 7)
                                                                .addComponent(this.pnlKeyboard,
                                                                        GroupLayout.DEFAULT_SIZE,
                                                                        GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                                .addGroup(
                                                        layout.createSequentialGroup()
                                                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                                .addComponent(this.cbProcess, 0,
                                                                        GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addComponent(this.cbRecentFiles, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
        layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup()
                        .addComponent(this.cbRecentFiles, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
                                GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(
                                layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(this.btnPlay)
                                        .addComponent(this.btnRecord).addComponent(this.btnOptions))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(
                                layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                                        .addGroup(
                                                layout.createSequentialGroup()
                                                        .addComponent(this.cbProcess, GroupLayout.PREFERRED_SIZE,
                                                                GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(this.pnlKeyboard, GroupLayout.PREFERRED_SIZE,
                                                                GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(this.pnlMouse, GroupLayout.PREFERRED_SIZE, 15,
                                                                GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(this.pnlStep, GroupLayout.PREFERRED_SIZE, 18,
                                                                GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(this.pnlTime, GroupLayout.PREFERRED_SIZE, 18,
                                                                GroupLayout.PREFERRED_SIZE))
                                        .addComponent(this.pnlZoom, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,
                                                Short.MAX_VALUE))));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * @param args
     *            the command line arguments
     */
    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }

        // </editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new Main().setVisible(true);
                } catch (IOException e) {
                    System.err.println("软件错误。请重新安装。");
                }
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnOptions;
    private javax.swing.JButton btnPlay;
    private javax.swing.JButton btnRecord;
    private javax.swing.JComboBox cbProcess;
    private javax.swing.JComboBox cbRecentFiles;
    private javax.swing.JLabel lblColor;
    private javax.swing.JLabel lblKeyboard;
    private javax.swing.JLabel lblMouse;
    private javax.swing.JLabel lblStep;
    private javax.swing.JLabel lblTime;
    private javax.swing.JPanel pnlKeyboard;
    private javax.swing.JPanel pnlMouse;
    private javax.swing.JPanel pnlStep;
    private javax.swing.JPanel pnlTime;
    private javax.swing.JPanel pnlZoom;

    // End of variables declaration//GEN-END:variables
    private Status status = Status.NORMAL;

    @Override
    public void actionPerformed(ActionEvent evt) {
        final String cmd = evt.getActionCommand();
        if ("options".equals(cmd)) {
            btnOptionsActionPerformed(evt);
        } else if ("play".equals(cmd)) {
            this.status = Status.PLAYING;
            startPlaying();
        } else if ("record".equals(cmd)) {
            this.status = Status.RECORDING;
            startCells();
        } else if ("stop".equals(cmd)) {
            if (this.status == Status.RECORDING) {
                stopCells();
            } else {
                startPlaying();
            }
        }
    }

    private void startPlaying() {
        // TODO Auto-generated method stub

    }

    private void startCells() {
        for (CellPlugin c : this.cells) {
            c.start();
        }
    }

    private void stopCells() {
        for (CellPlugin c : this.cells) {
            c.stop();
        }
    }

    private void btnOptionsActionPerformed(ActionEvent evt) {
        ClosableDialog dialog = new ClosableDialog(this, "编辑选项", true);
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        SettingsPanel panel = new SettingsPanel(dialog);
        dialog.getContentPane().add(panel);
        dialog.pack();
        dialog.setResizable(false);
        dialog.setLocation((Main.SCREEN_SIZE.width - dialog.getWidth()) / 2,
                (Main.SCREEN_SIZE.height - dialog.getHeight()) / 2);
        dialog.setVisible(true);
        // TODO
    }
}
